package cn.edu.neu.lab603.cloudeval.strategy

import cn.edu.neu.lab603.cloudeval.entity.{DataCenter, PhysicalMachine, VirtualMachine}
import cn.edu.neu.lab603.cloudeval.strategy.policy.{HostSelectionPolicy, ReAllocationTimePolicy, VMSelectionPolicy}

/** 使用三个步骤的虚拟机迁移策略。
  *
  * Created by yfwz100 on 2016/11/3.
  */
class VMMigrationStrategy(val allocationTime: ReAllocationTimePolicy,
                          val pSelectionPolicy: HostSelectionPolicy,
                          val vSelectionPolicy: VMSelectionPolicy) extends ReallocationStrategy {

  /** 检查是否满足重分配条件.
    *
    * @return 是或否
    */
  override def checkResourcesViolation(dataCenter: DataCenter): Boolean = {
    implicit val dc = dataCenter
    allocationTime.isTimeForReallocation
  }

  /** 获得待迁移的虚拟机和实体机之间的映射关系。
    *
    * @return 映射关系
    */
  override def reallocate(dataCenter: DataCenter): scala.collection.Map[VirtualMachine, PhysicalMachine] = {
    implicit val dc = dataCenter
    pSelectionPolicy.getHostsToMigrate.view
      .flatMap(vSelectionPolicy.getVMFromMigratedHost)
      .map(v => v -> pSelectionPolicy.getHostForPlacement(v))
      .filter(_._2 != null)
      .toMap
  }

  override def cleanup(dataCenter: DataCenter): Unit = {
    implicit val dc = dataCenter
    pSelectionPolicy.getHostsToTurnoff.foreach(_.shutdown())
  }

  override def toString = s"$allocationTime-$pSelectionPolicy-$vSelectionPolicy"

}
